﻿using System.Diagnostics;
using System.Security.Claims;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Validation;
using Service.Auth.Api.Application.Query;
using Service.Auth.Domain.AggregatesModel;
using Service.Core.Redis.Services;
using Service.Core.Repository;
using Service.Framework.ApplicationEventBus;
using Duende.IdentityModel;

namespace Service.Auth.Api.Application.IdsValidator
{
    /// <summary>
    /// 角色授权手机号验证器
    /// </summary>
    public class RoleResourceOwnerPhoneValidator(
        IRepository<Role> roleRepository,
         IHttpContextAccessor httpContextAccessor,
        IApplicationEventBus applicationEventBus,
         IRedisService redisService, UserQueryService userQueryService, SystemQueryService systemQueryService)
        : BaseResourceOwnerValidator(httpContextAccessor, applicationEventBus, redisService, userQueryService, systemQueryService), IExtensionGrantValidator
    {
        /// <summary>
        /// 
        /// </summary>
        public string GrantType => "sms";
        /// <inheritdoc/>
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {

            var phone = context.Request.Raw.Get("phone");
            var code = context.Request.Raw.Get("code");
            var key = $"SendSmsLoginCode:{phone}";
            var redisCode = await redisService.Database.StringGetAsync(key);

            var userId = string.Empty;
            try
            {
                if (string.IsNullOrEmpty(phone))
                {
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "phone is not valid");
                    return;
                }
                if (string.IsNullOrEmpty(code))
                {
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "code is not valid");
                    return;
                }
                if (!redisCode.HasValue || (string)redisCode! != code.Trim())
                {
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "手机验证码错误。");
                    return;
                }
                await redisService.Database.KeyDeleteAsync(key);


                var valiDate = await ValidateAsync(phone, context.Request.ClientId);
                if (valiDate.result != null)
                {
                    context.Result = valiDate.result;
                    return;
                }
                var user = valiDate.user;

                userId = user.Id.ToString();

                var roles = user.UserSystemRoles.Select(s => s.RoleNum).ToList();


                var claims = new List<Claim>
                {
                    new(JwtClaimTypes.Subject, user.Id.ToString()),
                    new("tenant_id", user.TenantId),
                };
                var claim = roles.Select(s =>
                    new Claim(JwtClaimTypes.Role, s)).ToArray();
                claims.AddRange(claim);

                //用户信息
                // 验证账号
                context.Result = new GrantValidationResult
                (
                    subject: user.Id.ToString(),
                    authenticationMethod: "custom",
                    claims: claims
                );
                await Task.CompletedTask;
            }
            catch (Exception ex)
            {

                context.Result = new GrantValidationResult()
                {
                    IsError = true,
                    Error = ex.Message
                };
            }
        }
    }
}